extends Object


class_name CharacterUnit


## 事件类型
enum Event {
    NONE = 0,

    ## 子弹发射事件
    ON_HIT_EXECUTE,
    ## 子弹命中目标事件
    ON_HIT_SOMETHING,
    ## 子弹销毁时未命中事件
    ON_HIT_NOTHING,
    ## 子弹飞出屏幕事件
    ON_HIT_OUT_OF_SCREEN,

    ## 击中敌人
    ON_HIT_ENEMY,
    ## 被敌人攻击
    ON_HIT_ATTACK,
    ## 对敌人造成伤害
    ON_HIT_HURT,
    ## 远程武器击杀敌人
    ON_HIT_KILL,

    ## 角色死亡
    ON_DIE,
}

enum Effect {
    NONE = 0,

    ## 击退效果
    DO_KNOCKBACK,
    ## 伤害效果
    DO_DAMAGE,
    ## 回复效果
    DO_HEALTH,
}

const EventDesc: Array[String] = [
    "NONE",
    "ON_HIT_EXECUTE",
    "ON_HIT_SOMETHING",
    "ON_HIT_NOTHING",
    "ON_HIT_OUT_OF_SCREEN",
    "ON_HIT_ENEMY",
    "ON_HIT_ATTACK",
    "ON_HIT_HURT",
    "ON_HIT_KILL",
    "ON_DIE",
]

const EffectDesc: Array[String] = [
    "NONE",
    "DO_KNOCKBACK",
    "DO_DAMAGE",
    "DO_HEALTH",
]


static func event(type: Event, meta: Dictionary[String, Variant]) -> CharacterEvent:
    var e: CharacterEvent = CharacterEvent.new()
    e.type = type
    e.meta = meta
    return e

static func post(character: CharacterComponent, type: Event, meta: Dictionary[String, Variant]) -> void:
    if character:
        var e: CharacterEvent = event(type, meta)
        e.meta["character"] = character
        character.post(e)

static func hit_execute(character: CharacterComponent, source: ProjectileResource, node: Projectile) -> bool:
    var e: CharacterEvent = event(Event.ON_HIT_EXECUTE,
    {
        "source": source,
        "projectile": node,
    })
    return character.on_message(e)

static func hit_something(character: CharacterComponent, node: Projectile, body: Node2D, body_rid: RID, hit_direction: Vector2, hit_normal: Vector2) -> bool:
    var e: CharacterEvent = event(Event.ON_HIT_SOMETHING,
    {
        "body": body,
        "body_rid": body_rid,
        "normal": hit_normal,
        "direction": hit_direction,
        "projectile": node
    })
    return character.on_message(e, node.processor)

static func hit_nothing(character: CharacterComponent, node: Projectile) -> bool:
    var e: CharacterEvent = event(Event.ON_HIT_NOTHING,
    {
        "projectile": node
    })
    return character.on_message(e, node.processor)

static func hit_out_of_screen(character: CharacterComponent, node: Projectile, hit_direction: Vector2) -> bool:
    var e: CharacterEvent = event(Event.ON_HIT_OUT_OF_SCREEN,
    {
        "projectile": node,
        "direction": hit_direction
    })
    return character.on_message(e, node.processor)
